#include "main.h"
#include "bsp_usart.h"
#include <string.h>
#include <stdio.h>
#include "stm32f4xx_it.h"

/************************************************
分隔线：
测试程序
测试app和bootlaoder之间来回跳转
*************************************************/
uint8_t connent_rx_flag = 0;                       //麦尔通接收到信息标志
// uint8_t connent_rx_buffer[BUFF_SIZE] = {0};
// uint32_t connent_rx_len = 0;

//串口接收数据处理函数
void usart3_Rx_Data_service(void)
{
    for (int i = 0; i < connent_rx_len; i++)
    {
        HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
        HAL_Delay(10);
        HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
        printf("%c", connent_rx_buffer[i]);
    }
}







/************************************************
分隔线：
下面是实际的程序
*************************************************/

// uint16_t calculate_crc16(const uint8_t *data, uint16_t length);//CRC校验函数

// uint8_t connent_rx_flag = 0;                       //麦尔通接收到信息标志
// // uint8_t connent_rx_buffer[BUFF_SIZE] = {0};
// // uint32_t connent_rx_len = 0;

// uint8_t flash_buf[FLASH_SIZE];


// #define HEADER_SIZE 3   //包头A2 2个字节
// #define CRC_SIZE 2		//CRC校验是  2个字节
// uint32_t flash_address = SYSTEM_APP_FLASH_ADDR; // Flash当前写入地址
// uint32_t received_size = 0;    // 记录已接收的数据大小
// uint32_t file_size=0;//bin包文件大小
// uint32_t total_received_size = 0; //总共收到的多少字节
// uint8_t flash_write_flag= 0;//flash写标志
// int32_t data_len=0;//每一次接收到有效数据的长度

// int16_t current_chunk_number=1;//记录当前是第几包（32记录的）
// int16_t receive_chunk_number=0;//收到的是第几包（网关发的）
// uint8_t  chunk_number_back_flag=0;//回复网关当前收到第几包的标志位


// uint8_t flash_start_flag;	 //开始程序更新标注位 
// uint8_t chunk_number_back[3]={0xA2,0x00,0x00};//回复网关当前收到哪一包





// /*
// * USART3 中断服务函数处理
// * 在stm32f4xx_it.c中
// */

// // void USART3_IRQHandler()
// // {
// // 	HAL_UART_IRQHandler(&huart3);// 判断是不是串口x
// // 	if(USART3 == huart3.Instance)//判断是不是空闲中断
// // 	{
// // 		if(RESET != __HAL_UART_GET_FLAG(&huart3, UART_FLAG_IDLE))
// // 		{// 清除空闲中断标志(不然会一直不断进入中断)
// // 			__HAL_UART_CLEAR_IDLEFLAG(&huart3);//中止本次DMA传输
// // 			HAL_UART_DMAStop(&huart3);//
// //             // 计算接收到的数据长度
// // 			connent_rx_len = BUFF_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart3_rx);
// // 			if(connent_rx_len>0)
// // 			{
// // 				usart3_Rx_Data_service();//数据处理函数
// // 			}
// // 			HAL_UART_Receive_DMA(&huart3, (uint8_t*)connent_rx_buffer, BUFF_SIZE);
// // 			// 清零接收缓冲区
// // 			memset(connent_rx_buffer, 0, connent_rx_len);
// // 			connent_rx_len = 0;
// // 		}
// // 	}
// // }

// /*
// * 串口发送函数
// * 参    数 ： buf 发送首地址   size发送字节数（小于128）
// */
// void Send_Data(UART_HandleTypeDef *huart,uint8_t *buf,uint8_t size)
// {
// 	size=size>BUFF_SIZE ? BUFF_SIZE:size;
// 	if(huart->Instance == USART3)
// 		HAL_UART_Transmit(&huart3,buf,size,0xffff);
// }



// //串口3接收数据处理函数
// void usart3_Rx_Data_service(void)
// {
// 	if(connent_rx_len ==4)//是包的大小
// 	{   // 将接收到的字节转换为文件大小（大端序）
// 	    file_size = (uint32_t)(connent_rx_buffer[0] << 24) | (uint32_t)(connent_rx_buffer[1] << 16) |
// 	                (uint32_t)(connent_rx_buffer[2] << 8) | (uint32_t)(connent_rx_buffer[3]);
// 	    if(file_size>3000)//文件的大小正确
// 	    {
// 	  	  uint8_t data_cmd[]={0xA2,0xA2};//告诉网关可以去要包了
// 	  	  Send_Data(&huart3,(uint8_t*)data_cmd,sizeof(data_cmd));
// 	    }
// 	    //这里是为了保证在出现发包发一半停止之后，重新从头发包导致写入地址错误
// 	    flash_address = SYSTEM_APP_FLASH_ADDR;//APP的起始地址
// 	    total_received_size = 0;
// 	    received_size = 0;
// 	    current_chunk_number= 1;
// 	}
// 	else
// 	{	// 获取有效数据长度 (总长度 - 包头 - CRC 校验)
// 		data_len = connent_rx_len - HEADER_SIZE - CRC_SIZE;
// 		if(data_len>0)
// 		{
// 			if (connent_rx_buffer[0] ==0xA2)//判读包头是否正确
// 			{
// 				//包数转换成10进制
// 				receive_chunk_number = (uint16_t)(connent_rx_buffer[1] << 8) | (uint16_t)(connent_rx_buffer[2]);

// 				if(current_chunk_number ==receive_chunk_number)//判断当前包数是否正确
// 				{
// 				 	// 提取接收到的 CRC 校验值（来自包尾的最后两个字节）
// 					uint16_t received_crc = (connent_rx_buffer[connent_rx_len - 2] << 8) | connent_rx_buffer[connent_rx_len - 1];

// 					// 计算除包头和包尾（CRC）之外的 CRC16 校验值
// 					uint16_t calculated_crc = calculate_crc16(&connent_rx_buffer[3], data_len);

// 					// 比较计算的 CRC16 和接收到的 CRC16
// 					if(calculated_crc == received_crc)  // CRC 校验通过
// 					//if((connent_rx_buffer[connent_rx_len - 2] == 0xA5) &&(connent_rx_buffer[connent_rx_len - 1] == 0xA5))
// 					{
// 						current_chunk_number++;//数据包数+1
// 						// 将去除包头和CRC校验的有效数据存储到 flash_buf 中
// 						memcpy(flash_buf+received_size, &connent_rx_buffer[HEADER_SIZE], data_len);
// 						total_received_size += data_len;//接收总长度计数
// 						received_size += data_len;//更新接收长度计数
// 						//告诉网关收到了哪个包，可以发下一个包了
// 						 if (received_size == FLASH_SIZE&& flash_write_flag == 0)
// 						 {//进行拷贝到内存中，收到的数据长度为4k，再往flash中写
// 							 flash_write_flag = 1;
// 							 chunk_number_back[1]=connent_rx_buffer[1];
// 							 chunk_number_back[2]=connent_rx_buffer[2];
// 						 }else
// 						 {
// 							//回复网关当前收到第几包
// 							chunk_number_back[1]=connent_rx_buffer[1];
// 							chunk_number_back[2]=connent_rx_buffer[2];
// 							Send_Data(&huart3,(uint8_t*)chunk_number_back,sizeof(chunk_number_back));
// 						 }
// 					}else
// 					{
// 						 // CRC 校验失败，可能需要重传该块
// 						//	handle_crc_error(current_chunk_number);
// 					}
// 				}

// //                if (received_size == FLASH_SIZE && flash_write_flag == 0)//已接收到flash_size大小数据
// //                {//进行拷贝到内存中，收到的数据长度为4k，再往flash中写
// //                	flash_write_flag = 1;
// //                }
//                 if(total_received_size == file_size && flash_write_flag == 0)
// 				{//文件接收完成
//                 	 flash_write_flag = 1;
// 				}
//                 if(flash_write_flag == 0)
// 				{
//                 	//应答-非拷贝数据时（最好一帧暂时不应答，等待拷贝到flash中后再应答）
// 				}
// 			}
// 		}
// 	}


// 	if(connent_rx_buffer[0] ==0xA3)
// 	{
// 		flash_start_flag = 0;
// 	}
// }






// /************************************************
// 函数名称 ： calculate_crc16
// 功    能 ：  CRC16 计算函数的实现，使用一个多项式 (通常为 CRC-CCITT 或 CRC-16-IBM)
// 参    数 ： 无
// 返 回 值 ： 无
// *************************************************/
// uint16_t calculate_crc16(const uint8_t *data, uint16_t length) {
//     uint16_t crc = 0xFFFF;  // 初始化 CRC 值

//     for (uint16_t i = 0; i < length; i++) {
//         crc ^= data[i];  // 将数据字节异或到当前 CRC 值

//         for (uint8_t j = 0; j < 8; j++) {
//             if (crc & 0x0001) {
//                 crc = (crc >> 1) ^ 0xA001;  // CRC 右移并与多项式异或
//             } else {
//                 crc >>= 1;  // CRC 右移
//             }
//         }
//     }

//     // 返回的 CRC 确保为大端序：高字节在前，低字节在后
//     //return (crc << 8) | (crc >> 8);
//     return crc;
// }